/*
 * Copyright (C) 2008-2011 CBDP Consortium
 * 
 * All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.
 * 
 * This software consists of contributions made by many individuals, 
 * listed below:
 *
 * Author: 	Xabier Laiseca <xabier.laiseca@deusto.es>
 * 			David Ausín <david.ausin@deusto.es>
 */
package cbdp.server.contextreasoner.impl.contextmanager.online.model;

import cbdp.server.contextreasoner.model.GenericProperty;
import cbdp.server.contextreasoner.model.exceptions.PreviouslyDeteledPropertyException;

import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.shared.Lock;

/**
 * @author Xabier Laiseca (University of Deusto)
 */
public abstract class EagerSavingGenericProperty implements GenericProperty
{
	private final static String PREVIOUSLY_DELETED_PROPERTY_EXCEPTION_MESSAGE = "The property has been previously deleted";
	
	protected OntModel ontModel;
	/**
	 * @uml.property  name="statement"
	 */
	protected Statement statement;
	
	protected boolean deleted = false;
	
	/**
     * @param ontModel
     * @uml.property  name="ontModel"
     */
	public void setOntModel(final OntModel ontModel)
	{
		this.ontModel = ontModel;
	}
	
	/**
     * @return
     * @uml.property  name="statement"
     */
	public Statement getStatement()
	{
		return statement;
	}
	
	/**
     * @param statement
     * @uml.property  name="statement"
     */
	public void setStatement(final Statement statement)
	{
		this.statement = statement;
	}

	@Override
	public final void delete() throws PreviouslyDeteledPropertyException
	{
		checkDeleted();
		
		ontModel.enterCriticalSection(Lock.WRITE);
		
		try
		{
			statement.remove();
		}
		finally
		{
			ontModel.leaveCriticalSection();
		}
		
		notifyDeleted();
		
		statement = null;
		ontModel = null;
		
		deleted = true;
	}
	
	protected void checkDeleted() throws PreviouslyDeteledPropertyException
	{
		if (deleted)
		{
			throw new PreviouslyDeteledPropertyException(PREVIOUSLY_DELETED_PROPERTY_EXCEPTION_MESSAGE);
		}
	}
	
	protected abstract void notifyDeleted();
}
